﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microhard.Permission.Interface;
using Microhard.Permission.Models;
using System.Text;
using Microhard.Permission;
using Microhard.Core.DBUtility;
using Microhard.Core;

namespace Microhard.Permission_MembershipImpl
{

    public class DataCollectionAuthImpl : IDataCollectionAuthorization
    {
        #region IRepository<DataCollection> Members

        public ExecutedResult Add(PermissionDataCollection model)
        {
            ExecutedResult rtn = new ExecutedResult();
            MicrohardOUGDBDataContext db = new MicrohardOUGDBDataContext();
            MicroHard_DataCollection op = model.ToEntity();
            op.DataCollectionID = Guid.NewGuid();
            op.CreateTime = DateTime.Now;
            db.MicroHard_DataCollections.InsertOnSubmit(op);
            try
            {
                db.SubmitChanges();
                rtn.Scope.IsSysManage = true;
            }
            catch (System.Exception ex)
            {
                rtn.ErrorMsg.Add("DataCollectionAuthImpl.Add", ex.Message);
                Log.Error("DataCollectionAuthImpl.Add", ex);
            }
            return rtn;
        }

        public ExecutedResult Update(PermissionDataCollection model)
        {
            ExecutedResult rtn = new ExecutedResult();
            MicrohardOUGDBDataContext db = new MicrohardOUGDBDataContext();
            var list = db.MicroHard_DataCollections.SingleOrDefault(n => n.DataCollectionID == model.DataCollectionID);

            if (list != null)
            {
                list.Scope = model.Scope;
                try
                {
                    db.SubmitChanges();
                }
                catch (Exception ex)
                {
                    rtn.ErrorMsg.Add("DataCollectionAuthImpl.Update", "修改失败，请联系系统管理员");
                    Log.Error("DataCollectionAuthImpl.Update", ex);
                }

            }

            return rtn;
        }

        public ExecutedResult Delete(List<Guid> ids)
        {
            ExecutedResult result = new ExecutedResult();
            MicrohardOUGDBDataContext db = new MicrohardOUGDBDataContext();
            var toDeltes = (from b in db.MicroHard_DataCollections
                            where ids.Contains(b.PermissionID)
                            select b).ToList();
            foreach (var d in toDeltes)
            {
                db.MicroHard_DataCollections.DeleteAllOnSubmit(toDeltes);
            }
            try
            {
                db.SubmitChanges();
            }
            catch (Exception ex)
            {
                result.ErrorMsg.Add("DataCollectionAuthImpl.Delete", ex.Message);
            }
            return result;
        }

        public ExecutedResult Delete(PermissionDataCollection model)
        {
            throw new NotImplementedException();
        }

        public PermissionDataCollection GetModelByID(Guid id)
        {
            MicrohardOUGDBDataContext db = new MicrohardOUGDBDataContext();
            var entity = db.MicroHard_DataCollections.SingleOrDefault(b => b.DataCollectionID == id);
            if (entity != null)
                return entity.ToModel();
            return null;
        }

        public PermissionDataCollection GetModelByModel(PermissionDataCollection model)
        {
            throw new NotImplementedException();
        }

        public List<PermissionDataCollection> Query(PermissionDataCollection Model, int pageIndex, int pageSize, out int totalCount)
        {
            throw new NotImplementedException();
        }

        public List<PermissionDataCollection> Query(PermissionDataCollection Model)
        {
            throw new NotImplementedException();
        }

        #endregion

        #region IDataCollectionAuthorization Members

        private void GetSubGroup(MicroHard_Group group, ref List<MicroHard_Group> allgroups)
        {
            if (group != null)
            {
                allgroups.Add(group);
            }
            if (group.GroupsChild == null || group.GroupsChild.Count == 0)
            {
                return;
            }
            foreach (var o in group.GroupsChild)
            {
                GetSubGroup(o, ref allgroups);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="permissionID"></param>
        /// <param name="currentUserID"></param>
        /// <returns></returns>
        public ScopeResult GetDataScope(Guid resourceID, User user)
        {
            ScopeResult result = null;
            #region 从数据库中获取数据权限
            result = new ScopeResult();
            result.PKID = new List<Guid>();

            MicrohardOUGDBDataContext db = new MicrohardOUGDBDataContext();
            //当前用户的角色
            var roleIDs = user.Roles.Select(r => r.RoleId);
            //根据ID获得datacollection
            var allDataScopes = db.MicroHard_DataCollections.Where(d => d.MicroHard_Permission.MicroHard_Resource.ResourceID == resourceID
                && (roleIDs.Contains(d.MicroHard_Permission.OwnerID)
                || d.MicroHard_Permission.OwnerID == user.ID)).OrderBy(p => p.Scope).ToList();
            //获得权限最大的dc
            var datacolls = allDataScopes.First();
            if (datacolls != null && resourceID != Guid.Empty)
            {
                result.OperationID = datacolls.MicroHard_Permission.MicroHard_Operation.OperationID;
                result.OperationName = datacolls.MicroHard_Permission.MicroHard_Operation.Name;
                result.OperationKeyName = datacolls.MicroHard_Permission.MicroHard_Operation.KeyName;
                result.ResourceID = datacolls.MicroHard_Permission.MicroHard_Resource.ResourceID;
                result.ResourceName = datacolls.MicroHard_Permission.MicroHard_Resource.Name;
                result.ResourceKeyName = datacolls.MicroHard_Permission.MicroHard_Resource.KeyName;
                result.Scope = (DataCollectionScope)Enum.Parse(typeof(DataCollectionScope), datacolls.Scope.ToString());
                result.CurrentUserID = user.ID;
                result.CurrentUserName = user.UserName;

                var ownerID = datacolls.OwnerID;
                switch (result.Scope)
                {
                    case DataCollectionScope.Custome:
                    case DataCollectionScope.All:
                    case DataCollectionScope.None:
                        break;
                    case DataCollectionScope.Group:

                        //获得当前角色/用户所在的组
                        var groupids = db.MicroHard_EntitiesInGroups.Where(g => (g.EntityID == user.ID
                            && g.EntityType == (int)OwnerIDType.User) ||
                            (roleIDs.Contains(g.EntityID) && g.EntityType == (int)OwnerIDType.Role)
                            ).Select(g => g.MicroHard_Group).ToList();

                        //获得组中的子组
                        List<MicroHard_Group> allgroups = new List<MicroHard_Group>();
                        foreach (var g in groupids)
                        {
                            this.GetSubGroup(g, ref allgroups);
                        }

                        //获得可以访问的数据的PKID
                        result.PKID = (from pe in db.MicroHard_DataPermissions
                                       where allgroups.Select(g => g.OrgID).Contains(pe.MicroHard_Resource.MicroHard_Group.OrgID)
                                       && pe.ResourceID == resourceID
                                       select pe.DataID.Value).ToList();
                        break;
                    case DataCollectionScope.Self:
                        //获得可以访问的数据的PKID
                        result.PKID = (from pe in db.MicroHard_DataPermissions
                                       where pe.OperatorID == user.ID
                                       && pe.ResourceID == resourceID
                                       select pe.DataID.Value).ToList();
                        break;
                    case DataCollectionScope.Specific:
                        //获得此用户的特殊权限用户范围
                        var userInGroup = (from spc in db.MicroHard_DataCollectionScopeSpecifics
                                           where spc.DataCollectionID == datacolls.DataCollectionID
                                           && spc.EntityType == (int)OwnerIDType.User
                                           select spc.EntityID).ToList();
                        userInGroup.Add(user.ID);
                        result.PKID = (from pe in db.MicroHard_DataPermissions
                                       where userInGroup.Contains(pe.OperatorID.Value)
                                       && pe.ResourceID == resourceID
                                       select pe.DataID.Value).ToList();
                        break;
                }
            }
            #endregion
            return result;
        }

        #endregion

        #region IDataCollectionAuthorization Members


        public bool IsDuplicate(Guid permissionID, int scope)
        {
            MicrohardOUGDBDataContext db = new MicrohardOUGDBDataContext();
            var cnt = db.MicroHard_DataCollections.Count(d => d.PermissionID == permissionID && d.Scope == scope);
            if (cnt > 0)
                return true;
            return false;
        }

        #endregion

        #region IRepository<PermissionDataCollection> Members


        public ScopeResult scope
        {
            set;
            get;
        }

        #endregion

    }
}
